machid equ $bf98 ; for //c initialization
acia equ $c09a
aciaintr equ $5f9
;
closedriver dey  ; y now = 0
 sty openflag ; no longer open
 sty initparm+1 ; then sign off from the card
callinit equ *
 ifne opers-pascal
 ldx #>initparm
 ldy #<initparm ; cannot be 0
 else
 ldx adrinitparm
 ldy adrinitparm+1
 fin
 bne applebus ; this is bra, call card & return
;
;
;
slotadr equ cmndlist+2 ; zp usage for opendriver
slotcount equ cmndlist+4
opendriver equ *
 ldx openflag
 bmi openerr1
 stx slotadr ; openflag is zero, therefore x is 0
 inx ; x = 1, i.e. assume slot is given
 and #7 ; slot number is in acc
 bne opndrv.1 ; we have a slot, search there
 lda #7 ; start with slot 7
 tax ; and search 7 slots
opndrv.1 equ * ; find a slot with a appletalk card
 ora #$c0 ; generate slot number
 sta slotadr+1
 stx slotcount ; number of slots to search
opndrv.1a ldx #7 ; look at 4 id bytes
opndrv.1b ldy cmptable,x
opndrv.1c lda (slotadr),y
 dex
 cmp cmptable,x
 beq opndrv.1d
 dec slotadr+1 ; wrong id byte, not appletalk card
 dec slotcount
 bne opndrv.1a
 lda #nointcard ; card not found
 bne openerr1+2 ; error, bra
openerr1 lda #alreadyopen
 sta status
 rts
opndrv.1d dex
 bpl opndrv.1b ; check more bytes
 lda slotadr+1 ; right id byte, this is slot number
opndrv.2 sta cardslot
 ldy #$ff
 lda (slotadr),y ; get version number of card
 sta cardversion
 ldy #3
 lda (cmndlist),y ; get node number
 sta initparm+1
 jsr callinit
 bne opendone ; return if error
 lda #0
 sta prtclhandler+1
 sta usertimer+1
 sta nbphook+1
 sta a.bridge
;initialize socket table, atprqtable 
 ldx #listentable-ddptable-2
 sta ddptable+1,x
 dex
 bne *-4
 do twoc
 ifeq opers-prodos
 lda machid
 and #$c8
 cmp #$88
 bne nottwoc
 lda acia
 ora #$0f
 sta acia
 lda #$c0
 sta aciaintr
nottwoc equ *
 fin
 fin
 do twoc
 ifeq opers-kernel
 lda $fbb3
 cmp #$06
 bne nottwoc
 lda $fbc0
 cmp #$40
 bcs nottwoc
 lda acia
 ora #$0f
 sta acia
 lda #$c0
 sta aciaintr
nottwoc equ *
 fin
 fin
 ifne opers-pascal
 ldx #>startparm
 ldy #<startparm
 else
 ldx adrstartparm
 ldy adrstartparm+1
 fin
 jsr applebus ; start timer and bus interrupt
 lda initparm+1 ; get node number
 sta ournode ; also save for our own use
 ldy #1 ; copy the data to be returned to caller
opendrv.4 lda cardslot-1,y
 sta (cmndlist),y
 iny
 ifeq opers-prodos
 cpy #7 ; prodos copy up to mlibypass
 else
 cpy #5 ; others copy up to interrupt handler
 fin
 bne opendrv.4
 lda #$80
 sta openflag
opendone rts
;
cmptable dfb $9b,$0c,$01,$0b,$18,$07,$38,$05
;
 ifeq opers-pascal
adrstartparm dw startparm
adrinitparm dw initparm
 fin
;
;
;
hookadr equ cmndlist+2
;
sethook equ * ; set various hook into driver
 php
 sei ; we must disable interrupt first
 asl a ; offset into table, high bit in carry
 tax
 bcs sethk.5 ; getinfo
 lda hooktable,x
 sta hookadr
 lda hooktable+1,x
 sta hookadr+1
 cpx #hooksize ; is it in range
 bcs sethk.9 ; no
sethk.3 iny ; now y is 2
 lda (cmndlist),y
 sta (hookadr),y
 cpy #3
 bne sethk.3
 plp
 rts
sethk.5 cpx #4 ; is it in range
 bcs sethk.9
sethk.7 iny ; y is now 2
 lda version,x
 sta (cmndlist),y
 inx
 cpy #3
 bne sethk.7
 plp
 rts
sethk.9 lda #illegalvalue
 bne opnskt.8 ; return error and pop stack
;
hooktable equ * ; all address must be two less bacause y is 2
 dw prtclhandler-2
 dw usertimer-2
 dw nbphook-2
hooksize equ *-hooktable
;
;
;
openddpsckt equ * ; open a ddp socket
 pha
 ldy #3
 lda (cmndlist),y ; get listener address
 tax
 iny
 lda (cmndlist),y
 tay
 pla
getnscktno jsr opensckt ; open the socket
 ldy #2
 sta (cmndlist),y ; return socket id
 rts
;
; internal subroutine to open a socket
;
opensckt equ *
 php
 sei
 stx sktlst.lo
 sty sktlst.hi
 tay
 bmi opnskt.6 ; illegal socket number if > $7f
 beq opnskt.1 ; dynamic, no search
 jsr srchscktable
 beq opnskt.7 ; duplicate
 lda #0
opnskt.1 jsr srchscktable ; find open entry
 bne opnskt.7 ; table full
 tya ; get back socket
 bne opnskt.2 ; well known, put it in
 txa ; dynamic, generate one
 adc #$7f ; remember that carry was set
opnskt.2 sta ddptable,x
 tay
 txa
 asl a
 tax ; x = x * 2
sktlst.lo equ *+1
 lda #0
 sta listentable,x
sktlst.hi equ *+1
 lda #0
 sta listentable+1,x
 plp
 tya ; get back socket #
 rts
opnskt.6 lda #badsocket
 bne opnskt.8
opnskt.7 lda #socketopen
opnskt.8 sta status
 plp
 lda #0 ; if error, return socket number 0
 rts
;
chkvalidsckt equ * ; check for valid socket #, if not exit with error
 cmp #3 ; do not use rtmp and nbp
 bcc chksckt.8
chkopensckt jsr srchscktable ; look for it in socket table
 beq clseddp.9 ;  found
chksckt.8 lda #scktnotopen
 sta status
 rts
;
clsatp.8 plp
 rts
 fin
;
;
atprqptr equ cmndlist+2
;
;
closeddpsckt equ *
 jsr chkvalidsckt
 bne clseddp.9
 lda #0
 sta ddptable,x
 txa
 asl a
 tax
 lda #0 ; zero out parameter links header.
 sta atprptable+1,x
 do safeclose
 lda atprptable+1,x
 beq clseddp.9
 sta atprqptr+1
 lda atprptable,x
 sta atprqptr
 lda #0
 sta atprptable+1,x
clsatp.1 ldy #1
 lda #reqabort ; misc error
 sta (atprqptr),y
 jsr nextinqueue
 bne clsatp.1
 else
 lda #0
 sta atprptable+1,x
 fin
clseddp.9 rts
;
srchscktable equ *
 ldx #ddptblsiz-1
srcsckt1 cmp ddptable,x
 beq srcsckt9 ; found, return with carry set
 dex
 bpl srcsckt1 ; ddptblsiz must be less than 128
srcsckt9 rts
;
;
startparm dfb 4
 dfb $80 ; enable both timer and packet interrupt
;
initparm dfb 1
 dfb 0
;
ddptblsiz equ 8
ddptable dfb 1,2
 ds ddptblsiz-2,0 ; rest of the table
processtable equ *
nbpptrsave ds 2,0
rspcbsize equ 4
rspcbbegin equ *-processtable
rspcbtable ds rspcbsize*2,0
rspcbend equ *-processtable
atprqtblsiz equ 4
atprqbegin equ *-processtable
atprqtable ds atprqtblsiz*2,0
atprqend equ *-processtable
atprptable equ *-4
 ds ddptblsiz*2-4,0
listentable dw rtmplisten,nbplisten ; built-in listener table
 ds ddptblsiz*2-4,0 ; rest of listener table
